import { readFileSync, writeFileSync } from 'node:fs'
import { resolve } from 'node:path'
import glob from 'fast-glob'
import { genKey } from './genKey.js'
import babel from '@babel/parser'
import { parse as parseVue } from '@vue/compiler-sfc'
import { extractCode } from './extractCode.js'
import type { Config } from './config.js'
import chalk from 'chalk'
import { extractPure } from './extractPure.js' // 顶部加导入

export async function performReplace(
  srcDir: string,
  cfg: { fn: string; ext: string[] }
): Promise<number> {
  const jscodeshift = await import('jscodeshift').then((m) => m.default)
  const patterns = cfg.ext.map((e) => `**/*.${e}`)
  const files = await glob(patterns, {
    cwd: srcDir,
    ignore: ['node_modules/**'],
  })
  const [ns, method] = cfg.fn.includes('.') ? cfg.fn.split('.') : ['', cfg.fn]
  const call = ns ? `${ns}.${method}` : method

  let count = 0
  for (const f of files) {
    const full = resolve(srcDir, f)
    const source = readFileSync(full, 'utf-8')

    try {
      if (f.endsWith('.vue')) {
        const { descriptor } = parseVue(source, { filename: full })
        const block = descriptor.script || descriptor.scriptSetup
        if (!block) continue

        const { start, end } = block.loc
        const realCode = extractCode(block.content) // 👈 只处理非注释
        const replaced = jscodeshift(realCode, {
          parser: {
            parse: (code: string) =>
              babel.parse(code, {
                sourceType: 'module',
                plugins: [
                  'jsx',
                  'typescript',
                  'decorators-legacy',
                  'classProperties',
                ],
              }),
          },
        })
          .find(jscodeshift.Literal)
          .filter((p: any) => {
            const v = p.value.value
            return (
              typeof v === 'string' &&
              /[\u4e00-\u9fa5]/.test(v) &&
              !v.includes('$')
            )
          })
          .replaceWith((p: any) => `${call}('${genKey(p.value.value)}')`)
          .toSource()

        if (replaced === realCode) continue
        const before = source.slice(0, start.offset)
        const after = source.slice(end.offset)
        const newBlock = source
          .slice(start.offset, end.offset)
          .replace(block.content, replaced)
        writeFileSync(full, before + newBlock + after)
        count++
      } else {
        const realCode = extractCode(source) // 👈 只处理非注释
        const out = jscodeshift(realCode, {
          parser: {
            parse: (code: string) =>
              babel.parse(code, {
                sourceType: 'module',
                plugins: [
                  'jsx',
                  'typescript',
                  'decorators-legacy',
                  'classProperties',
                ],
              }),
          },
        })
          .find(jscodeshift.Literal)
          .filter((p: any) => {
            const v = p.value.value
            return (
              typeof v === 'string' &&
              /[\u4e00-\u9fa5]/.test(v) &&
              !v.includes('$')
            )
          })
          .replaceWith((p: any) => {
            const raw = p.value.value
            const pure = extractPure(raw)
            if (!pure.length) return raw // 无中文原样返回
            // 只替换第一个中文片段（可扩展为全部）
            return raw.replace(pure[0], `${call}('${genKey(pure[0])}')`)
          })
          .toSource()

        if (out !== realCode) {
          writeFileSync(full, out)
          count++
        }
      }
    } catch (err) {
      console.warn(
        chalk.yellow(
          `⚠️  跳过无法解析的文件：${f} （${(err as Error).message}）`
        )
      )
    }
  }
  return count
}
